####TODO: add last connection date/time to disconnect.
# echo server
import socket
import select
import commands
import player
import login
import configurethis
import mobile
import event
###### queue import stuff
from collections import deque


commander = commands.commands()
configy = configurethis.Configit()
playerstuff = player.player()
mobstuff = mobile.mobile()
events = event.event()
######################################################################
#server stuff below
####################################################################
class server:
    debugserv = 0
    spawndebug = 1
    HOST = ''
    PORT = configy.portcfg
    s = ''
    ######### make sure to add a space under login for now.
    loginplaceholder = """
     @@@@@    Welcome to
   @@@@@@@@0       __  __         _    _        __  __               
  @@@@@@@@@00     |  \/  |_  _ __| |__| |_  _  |  \/  |___  ___ _ _  
 @@@@@@@@@000*    | |\/| | || / _` / _` | || | | |\/| / _ \/ _ \ ' \ 
  @@@@@@0000*     |_|  |_|\_,_\__,_\__,_|\_, | |_|  |_\___/\___/_||_|
   @0000000*                             |__/                        
     0000*            Tentatively, anyway

___Login?(login)        ____ Create a new character?(new)


"""
    connections = []
    readable = []
    writeable = []
    errored = []
    looper = 0
    inputs = []
    gmessages= deque([])
    #list of mobile dicts
    mobilesz = []
    def create(self):
        #some server making stuff
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.bind((self.HOST, self.PORT))
        self.s.listen(1)
    def process(self):
        #socket object into list for select
        read_list = [self.s]
        read_list.extend(self.inputs)
        #select to check sockets for ready and interval for timeout till we fix select
        self.readable, self.writeable, self.errored = select.select(read_list, self.inputs,[],0.4)
        
        for err in self.errored:
            for crr in self.connections:
                if err == crr['conn']:
                    crr['conn'].shutdown(2)
                    crr['conn'].close()


        
        #go through sockets that are readable
        
        for i in self.readable:
                #if readable obj is in socket "self.s" then we can accept
            if i is self.s:
                #accepts the connection
                conn, addr = self.s.accept()
                self.inputs.append(conn)
                initmode = 0
                pimport = {}
                pimporttemp={}
                self.connections.append({'conn': conn, 'addr': addr, 'data':deque([]), 'events': deque([]), 'out':deque([]), 'pdata':pimport, 'connection_mode':initmode, 'pdata_temp':pimporttemp, 'stat_q':deque([]), 'effect_q':deque([])})
                print('booop')
                #placeholder login message
                #for ac in self.connections:
                    
                   # ac['out'].append(self.loginplaceholder)
            else:
        
            #check if it's in readable but NOt a new socket to be made
                
                for cn in self.connections:
                    if i == cn['conn']:
                        try:
                            cn['data'].append(cn['conn'].recv(1024))
                        except:
                            playerstuff.lastconnsav(cn['pdata'])
                            cn['conn'].close()
                            self.inputs.remove(cn['conn'])
                            self.connections.remove(cn)
          
        for w in self.writeable:
            #print('WE IN WRITEABLE')
            for cw in self.connections:
                if w == cw['conn']:
                    if cw['out']:
                        try:
                            print('trying to send back!')
                            cwholder = cw['out'].popleft()
                            cw['conn'].sendall(cwholder.encode('utf-8'))
                        except:
                            playerstuff.lastconnsav(cw['pdata'])
                            cw['conn'].close()
                            self.inputs.remove(cw['conn'])
                            self.connections.remove(cw)
                
        #####useful debugs
        if self.debugserv == 1:
            print("connections list")
            print(self.connections)
            #print("readable")
            #print(self.readable)
            # print("writeable")
            #print(self.writeable)
            #self.looper += 1
            #print("looper"+str(self.looper))
        if self.spawndebug == 1:
            self.spawndebug = 0
            self.mobilesz.append(mobstuff.load_test_mobile("spawn"))
    def process_commands(self):
        #takes commands from 'data', runs threm through the command reader and adds the output to 'out'
                    #if pw['data']:
                #pw['out'].append(commander.read_input(pw['data'].popleft().decode('utf-8')))
        if self.connections:
            for pw in self.connections:

            ## REFITTING STUFF TO JUST READ ENTIRE DICT
                #try:
                commander.read_input(pw)
                #except:
                     #pw['conn'].close()
                     #self.inputs.remove(pw['conn'])
                     #self.connections.remove(pw)
        

    ############# global say processor
    def process_all_chat(self):
        if self.connections:
            for ch in self.connections:
                if ch['connection_mode'] == 2:
                    if ch['data']:
                        sayproczero = ch['data'].copy()
                        sayprocone = sayproczero.popleft().decode('utf-8')
                        sayproczero.clear()
                        if sayprocone.startswith('say '):
                            #sayprocone= ch['data'].popleft().decode('utf-8')
                            sayproctwo = ch['data'].popleft().decode('utf-8').lstrip('say ').strip('\n')
                            self.gmessages.append(ch['pdata']['character_a'] + " says, \"" + sayproctwo +"\""+"\n")
                        #else:
                            #ch['data'].append(str(sayprocone)).encode('utf-8')
        
        if self.gmessages:
            gmtemp = self.gmessages.popleft()
            mobstuff.mobile_all_check(gmtemp)
            for chm in self.connections:
                chm['out'].append(gmtemp)

            #send global to a mobile processing thing for mobs to read things?
            

    ####### global emote processor
    def process_emotes(self):
        pass
    def process_mob(self):
        #does some stuff to check actions?
        #feeds general chat for effects
        
        pass
    ########## tell processor (Private message)
    def process_tell_chat(self):
        #use map to
        #have something that checks players and mobiles to send messages
        
        pass
    ######movement and look processing
    def process_maps(self):
        #if self.connections:
            #for ch in self.connections:
                #if ch['connection_mode'] == 2:
                    #if ch['data']:
        pass
    def process_events(self):

        if self.connections:
            for ch in self.connections:
                if ch['connection_mode'] == 2:
                    if ch['events']:
                        events.event_in(ch)



    def debug_commander(self):
        #TODO: Implement maps to just show all players and mobs and handle things that way
        if self.connections:
            for chdd in self.connections:
                if chdd['connection_mode'] == 2:
                    if chdd['data']:
                        ddiszero = chdd['data'].copy()
                        ddisone = ddiszero.popleft().decode('utf-8')
                        ddiszero.clear()
                        if ddisone.startswith('00disp'):
                            
                           # ddisone= chdd['data'].popleft().decode('utf-8')
                            ddistwo = chdd['data'].popleft().decode('utf-8')
                            print(self.connections)
                            print(self.mobilesz)
                            #ddistwo = ch['data'].popleft().decode('utf-8').lstrip('say ').strip('\n')
                            #self.gmessages.append(ch['pdata']['character_a'] + " says, \"" + sayproctwo +"\""+"\n")
                        #else:
                            #ch['data'].append(str(sayprocone)).encode('utf-8')
                        if ddisone.startswith('00testm'):
                            ddistwo = chdd['data'].popleft().decode('utf-8')
                            chdd['out'].append("spawning").encode('utf-8')
                            print("spawning test")

                            
        
        
